home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / prog / dosref23.zip / CHAPTER.009 < prev    next >
Text File  |  1992-03-16  |  51KB  |  977 lines

  1.  
  2.        **  Programmer's Technical Reference for MSDOS and the IBM PC **
  3.                 USA copyright TXG 392-616  ALL RIGHTS RESERVED
  4. ───────────────────────────────┤ DOSREF (tm) ├────────────────────────────────
  5.                      ISBN 1-878830-02-3 (disk-based text)
  6.                     Copyright (c) 1987, 1992 Dave Williams
  7.                         ┌─────────────────────────────┐
  8.                         │ Shareware Version, 03/16/92 │
  9.                         │  Please Register Your Copy  │
  10.                         └─────────────────────────────┘
  11.  
  12.  
  13.                             C H A P T E R   N I N E
  14.  
  15.  
  16.                           INSTALLABLE DEVICE DRIVERS
  17.  
  18.  
  19.                                 C O N T E N T S
  20.  
  21. Device Driver Format .................................................... 9**
  22. Types of Devices ........................................................ 9**
  23.         Character Devices ............................................... 9**
  24.         Block Devices ................................................... 9**
  25. Device Header ........................................................... 9**
  26.         Pointer to Next Device Header Field ............................. 9**
  27.         Attribute Field ................................................. 9**
  28.                 Bits 0 and 1 ............................................ 9**
  29.                 Bit 2 ................................................... 9**
  30.                 Bit 3 ................................................... 9**
  31.                 Bit 13 .................................................. 9**
  32.                 Bit 14 .................................................. 9**
  33.                 Bit 15 .................................................. 9**
  34.         Pointer to Strategy and Interrupt Routines ...................... 9**
  35.         Name/Unit Field ................................................. 9**
  36. Creating a Device Driver ................................................ 9**
  37. Installing Device Drivers ............................................... 9**
  38.         Installing Character Devices .................................... 9**
  39.         Installing Block Devices ........................................ 9**
  40. Request Header .......................................................... 9**
  41.         Unit Code Field ................................................. 9**
  42.         Command Code Field .............................................. 9**
  43.         Status Field .................................................... 9**
  44. Device Driver Functions ................................................. 9**
  45.         INIT ............................................................ 9**
  46.         MEDIA CHECK ..................................................... 9**
  47.         Media Descriptor Byte ........................................... 9**
  48.         BUILD BPB (BIOS Parameter Block) ................................ 9**
  49.         INPUT OR OUTPUT ................................................. 9**
  50.         NONDESTRUCTIVE INPUT NO WAIT .................................... 9**
  51.         STATUS .......................................................... 9**
  52.         FLUSH ........................................................... 9**
  53.         OPEN or CLOSE (DOS 3.0+) ........................................ 9**
  54.         REMOVEABLE MEDIA (DOS 3.0+) ..................................... 9**
  55. The CLOCK$ Device ....................................................... 9**
  56.  
  57.  
  58.  
  59.  
  60. DEVICE DRIVER FORMAT├──────────────────────────────────────────────────────────
  61.  
  62.  A device driver is a handler for communication between the system software
  63. and hardware devices. The motherboard ROM and IBMBIO.COM or IO.SYS files
  64. contain the basic drivers for allowing DOS to talk to the console, disk drives,
  65. serial and parallel ports, clock, and other resources.
  66.  
  67.  DOS has five builtin drivers, STDIN, STDOUT, STERR, STDPRN, or STDAUX. An
  68. "installable" driver may be loaded in the CONFIG.SYS file, and either replace
  69. one of the builtin drivers or define a new resource, such as a mouse or
  70. expanded memory driver.
  71.  
  72.  The device driver is a COM (memory image) file that contains all of the code
  73. needed to control an add-in device. An EXE file should not be used since the
  74. EXE loader in some DOS 2.x versions is part of COMMAND.COM, which is not
  75. present when the device driver is being loaded by IBMBIO.COM or IO.SYS. EXE
  76. format drivers could be used in DOS 3.x+, but there is generally no reason to
  77. do so. The COM file must not load at the usual ORG 100h. Since the driver does
  78. not use the Program Segment Prefix, it is simply loaded without offset,
  79. therefore the driver file must have an origin of 0. Most references advise
  80. "ORG 0 or no ORG statement", however with the advent of many new assemblers on
  81. the market, some of which default to .COM files, specifically stating "ORG 0"
  82. may eliminate problems. Driver files should not have a declared stack segment.
  83.  
  84.  DOS can install the device driver anywhere in memory, so care must be taken
  85. in any FAR memory references. You should not expect that your driver will be
  86. loaded in the same place every time.
  87.  
  88.  
  89.  
  90.  
  91. TYPES OF DEVICES├──────────────────────────────────────────────────────────────
  92.  
  93.  There are two types of devices: Character devices and Block devices. Their
  94. attributes are as follows:
  95.  
  96.  Character devices are designed to do serial I/O in a byte-by-byte manner.
  97. These devices have names like CON, AUX, or PRN, and you can open channels
  98. (handles or FCBs) to do I/O much like a disk file. I/O may be in either cooked
  99. or raw mode. (see Chapter 7 for discussion of cooked and raw modes). Because
  100. character devices have only one name, they can only support one device.
  101.  
  102.  Block devices are normally implemented as disk drives. They can do random I/O
  103. in pieces called blocks, which are usually the physical sector size of the disk.
  104. These devices are not named as character devices are, and cannot be opened
  105. directly. Instead they are accessed by using drive letters such as A, B, C,
  106. etc. Block devices can have units within them. In this way, a single block
  107. driver can be responsible for one or more disk drives. For example, the first
  108. block device driver can be responsible for drives A, B, C, and D. This means it
  109. has four units defined and therefore takes up four drive letters. The position
  110. of the driver in the chain of all drives determines the way in which the drive
  111. letters correspond, i.e, if a second block device driver defines three units,
  112. then those units are E, F, and G.
  113.  
  114.  DOS 1.x allows 16 block devices. DOS 2.x allows 63, and DOS 3.x allows 26. It
  115. is recommended that drivers limit themselves to 26 devices for compatibility
  116. with DOS 3.x and 4.x. When DOS 2.x passes the Z: drivespec, the drivespecs get
  117. a little wierd, such as ^, [, or #. DOS 3.x+ will return an error message.
  118.  
  119.  
  120.  
  121.  
  122. CREATING A DEVICE DRIVER├──────────────────────────────────────────────────────
  123.  
  124.  To create a device driver that DOS can install, you must do the following:
  125.  
  126. 1) Create a memory image (COM) file with a device header at the start of the
  127.    file.
  128. 2) Originate the code (including the device header) at 0, instead of 100h.
  129. 3) Set the next device header field. Refer to "Pointer to Next Device Header
  130.    Attribute Field" for more information.
  131. 4) Set the attribute field of the device header. Refer to "Attribute Field" for
  132.    more information.
  133. 5) Set the entry points for the interrupt and strategy routines.
  134. 6) Fill in the name/unit field with the name of the character device or the
  135.    unit number of the block device.
  136.  
  137.  DOS always processes installable character device drivers before handling the
  138. default devices. So to install a new CON device, simply name the device CON.
  139. Be sure to set the standard input device and standard output device bits in
  140. the attribute field of a new CON device. The scan of the device list stops on
  141. the first match so the installable device driver takes precedence. For
  142. instance, installing ANSI.SYS replaces the builtin CON driver.
  143.  
  144.  DOS doesn't care about the position of installed character devices versus
  145. block devices.
  146.  
  147.  
  148.  
  149.  
  150. STRUCTURE OF A DEVICE DRIVER├──────────────────────────────────────────────────
  151.  
  152.  A device driver consists of three major parts:
  153.         a device header
  154.         a strategy routine
  155.         an interrupt routine
  156.  
  157.  
  158. DEVICE HEADER
  159.  
  160.  The driver has a special header to identify it as a device and to define the
  161. strategy and interrupt entry points and its various attributes. This header is
  162. located at the beginning of the file. It contains a pointer to the next driver
  163. in the chain, the attributes of the device, offsets into the strategy and
  164. interrupt routines, and the device ID.
  165.  
  166.  This is the format of the device header:
  167.  
  168. ┌──────────────────────────────────────────────────────────────────────────────┐
  169. │                         D E V I C E    H E A D E R                           │
  170. ├───────┬────────┬─────────────────────────────────────────────────────────────┤
  171. │Offset │ Length │                       Description                           │
  172. ├───────┼────────┼─────────────────────────────────────────────────────────────┤
  173. │  00h  │  word  │  Pointer to next device header field, offset value          │
  174. ├───────┼────────┼─────────────────────────────────────────────────────────────┤
  175. │  02h  │  word  │  Pointer to next device header field, segment value         │
  176. ├───────┼────────┼─────────────────────────────────────────────────────────────┤
  177. │  04h  │  word  │  Attribute                                                  │
  178. ├───────┼────────┼─────────────────────────────────────────────────────────────┤
  179. │  06h  │  word  │  Pointer to device strategy routine (offset only)           │
  180. ├───────┼────────┼─────────────────────────────────────────────────────────────┤
  181. │  08h  │  word  │  Pointer to device interrupt routine (offset only)          │
  182. ├───────┼────────┼─────────────────────────────────────────────────────────────┤
  183. │  0Ah  │8 bytes │  Name/Unit field                                            │
  184. └───────┴────────┴─────────────────────────────────────────────────────────────┘
  185.  
  186.  
  187. POINTER TO NEXT DEVICE HEADER FIELD
  188.  
  189.  The device header field is a pointer to the device header of the next device
  190. driver. It is a doubleword field that is set by DOS at the time the device
  191. driver is loaded. The first word is the offset and the second word is the
  192. segment.
  193.  
  194.  If you are loading only one device driver, set the device header field to -1
  195. before loading the device. If you are loading more than one device driver, set
  196. the first word of the device driver header to the offset of the next device
  197. driver's header. Set the device driver header field of the last device driver
  198. to -1.
  199.  
  200.  
  201. ATTRIBUTE FIELD
  202.  
  203.  The attribute field is a word field used to identify the type of device this
  204. driver is responsible for. This field distinguishes between block and
  205. character devices and determines is selected devices are given special
  206. treatment. The attributes are:
  207.  
  208. ┌──────────────────────────────────────────────────────────────────────────────┐
  209. │                        A T T R I B U T E   F I E L D                         │
  210. ├──────────┬───────┬───────────────────────────────────────────────────────────┤
  211. │   word   │ attr. │                                                           │
  212. ├──────────┼───────┤                     description                           │
  213. │   bits   │  set  │                                                           │
  214. ├──────────┼───────┼───────────────────────────────────────────────────────────┤
  215. │     0    │   0   │   not current standard input device                       │
  216. │          │   1   │   current standard input device                           │
  217. ├──────────┼───────┼───────────────────────────────────────────────────────────┤
  218. │     1    │   0   │   not current standard output device                      │
  219. │          │   1   │   current standard output device                          │
  220. ├──────────┼───────┼───────────────────────────────────────────────────────────┤
  221. │     2    │   0   │   not current NUL device                                  │
  222. │          │   1   │   current NUL device                                      │
  223. ├──────────┼───────┼───────────────────────────────────────────────────────────┤
  224. │     3    │   0   │   not current CLOCK device                                │
  225. │          │   1   │   current CLOCK device                                    │
  226. ├──────────┼───────┼───────────────────────────────────────────────────────────┤
  227. │     4    │   0   │   standard CON I/O routines should be used                │
  228. │          │   1   │   fast screen I/O (int 29h) should be used                │
  229. ├──────────┼───────┴───────────────────────────────────────────────────────────┤
  230. │  5 - 10  │         "reserved for DOS" - unknown - should be set to 0         │
  231. ├──────────┼───────┬───────────────────────────────────────────────────────────┤
  232. │    11    │   0   │   doesn't support removeable media  (default for DOS 2.x) │
  233. │          │   1   │   supports removeable media         (DOS 3.0+ only)       │
  234. ├──────────┼───────┴───────────────────────────────────────────────────────────┤
  235. │    12    │         "reserved for DOS" - unknown - should be set to 0         │
  236. ├──────────┼───────┬───────────────────────────────────────────────────────────┤
  237. │    13    │   0   │   IBM format       (block devices)                        │
  238. │          │   1   │   non-IBM format   (block devices)                        │
  239. │          │   1   │   output till busy (character devices)                    │
  240. ├──────────┼───────┼───────────────────────────────────────────────────────────┤
  241. │    14    │   0   │   doesn't support IOCTL                                   │
  242. │          │   1   │   supports IOCTL                                          │
  243. ├──────────┼───────┼───────────────────────────────────────────────────────────┤
  244. │    15    │   0   │   block device                                            │
  245. │          │   1   │   character device                                        │
  246. └──────────┴───────┴───────────────────────────────────────────────────────────┘
  247.  
  248. note 1) If a bit in the attribute word is defined only for one type of device,
  249.         a driver for the other type of device must set that bit to 0.
  250.      2) For DOS 2.0 bits 4-12 must be off.
  251.  
  252.  
  253. BIT 1   is the standard input and output bit. It is used for character devices
  254.         only. Use this bit to tell DOS if your character device driver is the
  255.         new standard input device or standard output device.
  256.  
  257. BIT 2   is the NUL attribute bit. It is used for character devices only. Use it
  258.         to tell DOS if your character device driver is a NUL device. Although
  259.         there is a NUL device attribute bit, you cannot reassign the NUL
  260.         device or replace it with your own routine. This attribute exists for
  261.         DOS so that DOS can tell if the NUL device is being used.
  262.  
  263. BIT 3   is the clock device bit. It is used for character devices only. Default
  264.         is 0. You can use it to tell DOS if your character device driver is the
  265.         new CLOCK device.
  266.  
  267. BIT 4   is the "fast video output" bit. The default is 0, which uses the BIOS
  268.         for writing to the screen. When set, this bit uses int 29h for much
  269.         faster screen updates.
  270.  
  271. BITS 5-10  reserved for DOS, unknown. Should be set to 0.
  272.  
  273. BIT 11  is the open/close removeable media bit. Use it to tell DOS if the
  274.         device driver can handle removeable media. This bit is valid for DOS
  275.         3.0+ only. This bit was reserved in DOS 2.x. Since DOS 2.x does not
  276.         look at this bit, its use is backward compatible.
  277.  
  278. BIT 12  reserved for DOS, unknown. Should be set to 0.
  279.  
  280. BIT 13  is the non-IBM format bit. When used for block devices it affects the
  281.         operation of the BUILD BPB (BIOS parameter block) device call. For
  282.         character devices it indicates that the devices implements the OUTPUT
  283.         UNTIL BUSY device call.
  284.  
  285. BIT 14  is the IOCTL bit. It is used for both character and block devices. Use
  286.         it to tell DOS whether the device driver can handle control strings
  287.         through the IOCTL function call 44h.
  288.          If a device driver cannot process control strings, it should set bit
  289.         14 to 0. This way DOS can return an error if an attempt is made through
  290.         the IOCTL function call to send or receive control strings to the
  291.         device. If a device can process control strings, it should set bit 14
  292.         to 1. This way, DOS makes calls to the IOCTL input and output device
  293.         function to send and receive IOCTL strings.
  294.          The IOCTL functions allow data to be sent to and from the device
  295.         without actually doing a normal read or write. In this way, the device
  296.         driver can use the data for its own use, (for example, setting a baud
  297.         rate or stop bits, changing form lengths, etc.) It is up to the device
  298.         to interpret the information that is passed to it, but the information
  299.         must not be treated as a normal I/O request.
  300.  
  301. BIT 15  is the device type bit. Use it to tell the system the that driver is a
  302.         block or character device.
  303.  
  304.  
  305. POINTER TO STRATEGY ROUTINE
  306.  
  307.  This field contains a pointer to "device strategy" function in the driver.
  308. This function is called whenever a request is made to the driver, and must
  309. store the location of the request header from DOS. This pointer is a word
  310. value, and so must be in the same segment as the device header.
  311.  
  312.  
  313. POINTER TO INTERRUPT ROUTINE
  314.  
  315.  This field contains a pointer to the function which activates driver routines
  316. to perform the command in the current request header. This is called by DOS
  317. after the call to the strategy function, and should reset to the request header
  318. address stored by "strategy", to allow for the possibility of interrupts
  319. between the two calls. This pointer is a word value, and so must be in the same
  320. segment as the device header.
  321.  
  322.  
  323. NAME/UNIT FIELD
  324.  
  325.  This is an 8-byte field that contains the name of a character device or the
  326. number of units in a block device. For the character names, the name is
  327. left-justified and the space is filled to 8 bytes. For block devices, the
  328. number of units can be placed in the first byte. This is optional because DOS
  329. fills in this location with the value returned by the driver's INIT code. The
  330. other 7 bytes of the block device ID are reserved and should not be used.
  331.  
  332.  
  333.  
  334. INSTALLING DEVICE DRIVERS├─────────────────────────────────────────────────────
  335.  
  336.  DOS installs new device drivers dynamically at boot time by reading and
  337. processing the DEVICE command in the CONFIG.SYS file. For example, if you have
  338. written a device driver called RAMDISK, to install it put this command in the
  339. CONFIG.SYS file:
  340.                    DEVICE=[drive][path] RAMDISK [parameters]
  341.  
  342.  DOS makes a FAR call to the device driver at its strategy entry point first,
  343. using the request header to pass information describing what DOS wants the
  344. device driver to do.
  345.  
  346.  This strategy routine does not perform the request but rather queues the
  347. request or saves a pointer to the request header. The second entry point is
  348. the interrupt routine and is called by DOS immediately after the strategy
  349. routine returns. The interrupt routine is called with no parameters. Its
  350. function is to perform the operation based on the queued request and set up
  351. any return infromation.
  352.  
  353.  DOS passes the pointer to the request header in ES:BX. This structure consists
  354. of a fixed length header (Request Header) followed by data pertinent to the
  355. operation to be performed.
  356.  
  357. NOTE: It is the responsibility of the device driver to preserve the machine
  358.       state. For example, save all registers on entry and restore them on exit.
  359.  
  360.  The stack used by DOS has enough room on it to save all the registers. If more
  361. stack space is needed, it is the device driver's responsibility to allocate and
  362. maintain another stack.
  363.  
  364.  All calls to execute device drivers are FAR calls. FAR returns should be
  365. executed to return to DOS.
  366.  
  367.  
  368.  
  369. INSTALLING CHARACTER DEVICES
  370.  
  371.   One of the functions defined for each device is INIT. This routine is called
  372. only once when the device is installed and never again. The INIT routine returns
  373. the following:
  374.  
  375. A) A location to the first free byte of memory after the device driver, like a
  376.    TSR that is stored in the terminating address field. This way, the
  377.    initialization code can be used once and then thrown away to save space.
  378. B) After setting the address field, a character device driver can set the status
  379.    word and return.
  380.  
  381.  
  382.  
  383. INSTALLING BLOCK DEVICES
  384.  
  385.  Block devices are installed in the same way as character devices. The
  386. difference is that block devices return additional information. Block devices
  387. must also return:
  388.  
  389. A) The number of units in the block device. This number determines the logical
  390.    names the devices will have. For example, if the current logical device
  391.    letter is F at the time of the install call, and the block device driver INIT
  392.    routine returns three logical units, the letters G, H, and I are assigned to
  393.    the units. The mapping is determined by the position of the driver in the
  394.    device list and the number of units in the device. The number of units
  395.    returned by INIT overrides the value in the name/unit field of the device
  396.    header.
  397.  
  398. B) A pointer to a BPB (BIOS Parameter Block) pointer array. This is a pointer
  399.    to an array of "N" word pointers there "N" is the number of units defined.
  400.    These word pointers point to BPBs. This way, if all of the units are the
  401.    same, the entire array can point to the same BPB to save space.
  402.     The BPB contains information pertinent to the devices such as the sector
  403.    size, number of sectors per allocation unit, and so forth. The sector size of
  404.    the BPB cannot be greater than the maximum allotted size set at DOS
  405.    initialization time. This array must be protected below the free pointer set
  406.     by the return.
  407.  
  408. C) The media descriptor byte. This byte is passed to devices so that they know
  409.    what parameters DOS is currently using for a particular drive unit.
  410.  
  411.  Block devices can take several approaches. They can be "dumb" or "smart". A
  412. dumb device would define a unit (and therefore a BPB) for each possible media
  413. drive combination. Unit 0=drive 0;single side, unit 1=drive 0;double side, etc.
  414. For this approach, the media descriptor bytes would mean nothing. A smart
  415. device would allow multiple media per unit. In this case, the BPB table
  416. returned at INIT must define space large enough to acommodate the largest
  417. possible medias supported (sector size in BPB must be as large as maximum
  418. sector size DOS is currently using). Smart drivers will use the media
  419. descriptor byte to pass information about what media is currently in a unit.
  420.  
  421.  
  422.  
  423. REQUEST HEADER├────────────────────────────────────────────────────────────────
  424.  
  425.  The request header passes the information describing what DOS wants the
  426. device driver to do.
  427.  When a valid device driver command code or function is called by your
  428. application program, DOS develops a data structure called the "Request Header"
  429. in ES:BX and passes it to the strategy entry point. This structure consists of
  430. a 13-byte defined header which may be followed by other data bytes depending on
  431. the function requested.
  432.  It is the device driver's responsibility to preserve the machine state, for
  433. example, saving all registers including flags on entry and restoring them on
  434. exit. There is enough room on the stack when strategy or interrupt is called
  435. to do about 20 pushes. If more stack is needed, the driver should set aside
  436. its own stack space.
  437.  The fixed ("static") part of the request header is as follows:
  438.  
  439. ┌────────────────────────────────────────────────────────────────────────────┐
  440. │                        R E Q U E S T    H E A D E R                        │
  441. ├───────┬───────┬────────────────────────────────────────────────────────────┤
  442. │Offset │Length │                      F i e l d                             │
  443. ├───────┼───────┼────────────────────────────────────────────────────────────┤
  444. │  00h  │  byte │ Length in bytes of the request header plus any data at end │
  445. ├───────┼───────┼────────────────────────────────────────────────────────────┤
  446. │  01h  │  byte │ Unit code. Determines subunit to use in block devices      │
  447. │       │       │ (minor device)  Has no meaning for character devices       │
  448. ├───────┼───────┼────────────────────────────────────────────────────────────┤
  449. │  02h  │  byte │ Command code                                               │
  450. ├───────┼───────┼────────────────────────────────────────────────────────────┤
  451. │  03h  │  word │ Status                                                     │
  452. ├───────┼───────┼────────────────────────────────────────────────────────────┤
  453. │  05h  │8 bytes│ Reserved for DOS                                           │
  454. ├───────┼───────┼────────────────────────────────────────────────────────────┤
  455. │  0Ch  │varies │ Data appropriate for the operation                         │
  456. └───────┴───────┴────────────────────────────────────────────────────────────┘
  457.  
  458. REQUEST HEADER LENGTH FIELD
  459.  
  460.  The length in bytes of the total request header (0-255) plus any data at the
  461. end of the header.
  462.  
  463.  
  464. UNIT CODE FIELD
  465.  
  466.  The unit code field identifies which unit in a block device driver the request
  467. is for. For example, if a block device driver has three units defined, then the
  468. possible values of the unit code field would be 0, 1, and 2. This field is not
  469. valid for character devices.
  470.  
  471.  
  472. COMMAND CODE FIELD
  473.  
  474.  The command code invokes a specific device driver function. Functions 0
  475. through 12 are supported in all device drivers. Functions 13-15 are available
  476. only in DOS 3.0 or higher. Some functions are relevant for either character or
  477. block devices but not both; nonetheless all functions must have an executable
  478. routine present even if it does nothing but set the done flag in the return
  479. status word in the request header.
  480.  
  481.  The command code field in the request header can have the following values:
  482. ┌──────┬──────────────────┬────────────────────────────────────────────────────┐
  483. │ code │       name       │                     function                       │
  484. ├──────┼──────────────────┼────────────────────────────────────────────────────┤
  485. │   0  │ INIT             │ initialize driver for later use (used once only)   │
  486. │   1  │ MEDIA CHECK      │ block devices only, NOP for character devices      │
  487. │   2  │ BUILD BPB        │ block devices only, NOP for character devices      │
  488. │   3  │ IOCTL input      │ called only if device has IOCTL bit set            │
  489. │   4  │ INPUT            │ read data                                          │
  490. │   5  │ NONDESTRUCTIVE INPUT NO WAIT  character devices only                  │
  491. │   6  │ INPUT STATUS     │ character devices only                             │
  492. │   7  │ INPUT FLUSH      │ character devices only                             │
  493. │   8  │ OUTPUT           │ write data                                         │
  494. │   9  │ OUTPUT           │ write data with verify                             │
  495. │  10  │ OUTPUT STATUS    │ character devices only                             │
  496. │  11  │ OUTPUT FLUSH     │ character devices only                             │
  497. │  12  │ IOCTL OUTPUT     │ called only if device has IOCTL bit is set         │
  498. │  13  │ DEVICE OPEN      │ called only if OPEN/CLOSE/RM bit is set            │
  499. │  14  │ DEVICE CLOSE     │ called only if OPEN/CLOSE/RM bit is set            │
  500. │  15  │ REMOVEABLE MEDIA │ only if OPEN/CLOSE/RM bit set & device is block    │
  501. │  16  │ OUTPUT UNTIL BUSY│ only called if bit 13 is set & device is character │
  502. └──────┴──────────────────┴────────────────────────────────────────────────────┘
  503.  
  504.  The individual command codes are described later in this chapter.
  505.  
  506.  
  507.  
  508. STATUS FIELD
  509.  
  510.  The status word field is zero on entry and is set by the driver interrupt
  511. routine on return.
  512.  
  513. The status field in the request header contains:
  514.  
  515. ┌─────────────────────────────────────────────────────────────────────────────┐
  516. │            D E V I C E    D R I V E R    S T A T U S    F I E L D           │
  517. ├───────┬───┬─────────────────────────────────────────────────────────────────┤
  518. │ size  │bit│                        definition                               │
  519. ├───────┼───┼─────────────────────────────────────────────────────────────────┤
  520. │ byte  │ 0 │                                                                 │
  521. │       │ 1 │                                                                 │
  522. │       │ 2 │                                                                 │
  523. │       │ 3 │  Error message return code                                      │
  524. │       │ 4 │  (with bit 15=1)                                                │
  525. │       │ 5 │                                                                 │
  526. │       │ 6 │                                                                 │
  527. │       │ 7 │                                                                 │
  528. ├───────┼───┼─────────────────────────────────────────────────────────────────┤
  529. │ byte  │ 8 │  DONE                                                           │
  530. │       ├───┼─────────────────────────────────────────────────────────────────┤
  531. │       │ 9 │  BUSY                                                           │
  532. │       ├───┼─────────────────────────────────────────────────────────────────┤
  533. │       │ A │  Reserved by DOS, unknown                                       │
  534. │       │ B │                                                                 │
  535. │       │ C │                                                                 │
  536. │       │ D │                                                                 │
  537. │       │ E │                                                                 │
  538. │       ├───┼─────────────────────────────────────────────────────────────────┤
  539. │       │ F │  Error                                                          │
  540. └───────┴───┴─────────────────────────────────────────────────────────────────┘
  541.  
  542.  
  543.  The low 8 bits of the status word define an error message if bit 15 is set.
  544. These errors are:
  545.  
  546.         00h  write protect violation   01h  unknown unit
  547.         02h  device not ready          03h  unknown command
  548.         04h  CRC error                 05h  bad drive request structure length
  549.         06h  seek error                07h  unknown media
  550.         08h  sector not found          09h  printer out of paper
  551.         0Ah  write fault               0Bh  read fault
  552.         0Ch  general failure           0Dh  reserved
  553.         0Eh  reserved                  0Fh  invalid disk change
  554.  
  555. BIT 8   is the done bit. If it is set, it means the operation is complete. The
  556.         driver sets the bit to 1 when it exits.
  557.  
  558. BIT 9   is the busy bit. It is only set by status calls and the removable media
  559.         call.
  560.  
  561. BITS 10-14 are reserved.
  562.  
  563. BIT 15  is the error bit. If this bit is set, the low 8 bits of the status word
  564.         (7-0) indicate the error code.
  565.  
  566.  
  567. RESERVED FOR DOS
  568.  Official sources label this area as "reserved for DOS". Another source
  569. indicates that this consists of two double-word (4-byte) pointers to be used
  570. to maintain a linked list of request headers for this device and a list of all
  571. current device requests being processed by DOS. This was apparently to be used
  572. for the undelivered multitasking version of DOS.
  573.  
  574.  
  575.  
  576. DEVICE DRIVER FUNCTIONS├───────────────────────────────────────────────────────
  577.  
  578.  All strategy routines are called with ES:BX pointing to the request header.
  579. The interrupt routines get the pointers to the request header from the queue
  580. the strategy routines stores them in. The command code in the request header
  581. tells the driver which function to perform.
  582.  
  583. NOTE: All DWORD pointers are stored offset first, then segment.
  584.  
  585.                          ############################
  586.  
  587. INIT
  588. Command code = 0        (all devices)
  589.         Performs all initialization required at DOS boot time to install the
  590.         driver and set local driver variables. This function is called only
  591.         once, when the driver is loaded.
  592.  
  593.         ES:BX   pointer to 26-byte request header and data structure
  594.  Format of structure:
  595.        offset     length          field
  596.          00h    13 bytes   request header
  597.          0Dh       byte    number of units (not set by character devices)
  598.          11h       dword   ending address of the driver's resident code
  599.          15h       dword   pointer to BPB array (not set by character devices)
  600.                            /pointer to remainder of arguments
  601.          19h       byte    drive number (DOS 3.0+ only)
  602.  
  603.  
  604.  When INIT is called, the driver must do the following:
  605.  
  606.         A) set the number of units (block devices only)
  607.         B) set up the pointer to the BPB array (block devices only)
  608.         C) perform any initialization code (to modems, printers, etc)
  609.         D) set the ending address of the resident program code
  610.         E) set the status word in the request header
  611.  
  612.  To obtain information obtained from CONFIG.SYS to a device driver at INIT
  613. time, the BPB pointer field points to a buffer containing the information
  614. passed from CONFIG.SYS following the =. The buffer that DOS passes to the
  615. driver at INIT after the file specification contains an ASCII string for the
  616. file OPEN. The ASCII string (ending in 0h) is terminated by a carriage return
  617. (0Dh) and linefeed (0Ah). If there is no parameter information after the file
  618. specification, the file specification is immediately followed by a linefeed
  619. (0Ah).
  620.  
  621.  NOTE: This information is read-only and only system calls 01h-0Ch and 30h can
  622.        be issued by the INIT code of the driver.
  623.  
  624.  The last byte parameter contains the drive letter for the first unit of a
  625. block driver. For example, 0=A, 1=B etc.
  626.  
  627.  If an INIT routine determines that it cannot set up the device and wants to
  628. abort without using any memory, follow this procedure:
  629.  
  630.         A) set the number of units to 0
  631.         B) set the ending offset address at 0
  632.         C) set the ending offsret segment address to the code segment (CS)
  633.  
  634. NOTE: If there are multiple device drivers in a single memory image file, the
  635.       ending address returned by the last INIT called is the one DOS uses. It is
  636.       recommended that all device drivers in a single memory image file return
  637.       the same ending address.
  638.  
  639.                          ############################
  640.  
  641. MEDIA CHECK
  642. command code = 1        (block devices only)
  643.         Checks to see if disk had been changed since last access.
  644.  
  645.         ES:BX   pointer to 19-byte request header and data structure
  646.  Format of structure:
  647.         offset  length          field
  648.         00h     13 bytes   request header
  649.         0Dh        byte    media descriptor from BPB
  650.         0Eh        byte    returned
  651.         0Fh       dword    returns a pointer to the previous volume ID (if bit
  652.                            11=1 and disk change is returned) (DOS 3.0+)
  653.  
  654.  When the command code field is 1, DOS calls MEDIA CHECK for a drive unit and
  655. passes its current media descriptor byte. See "Media Descriptor Byte" later in
  656. this chapter for more information about the byte. MEDIA CHECK returns one of
  657. the following:
  658.  
  659.         A) media not changed             C) not sure
  660.         B) media changed                 D) error code
  661.  
  662. The driver must perform the following:
  663.         A) set the status word in the request header
  664.         B) set the return byte
  665.                 00h   don't know if media has been changed
  666.                 01h   media has not been changed
  667.                 -1    media has been changed
  668.  
  669.  DOS 3.0+: If the driver has set the removable media bit 11 of the device header
  670. attribute word to 1 and the driver returns -1 (media changed), the driver must
  671. set the DWORD pointer to the previous volume identification field. If DOS
  672. determines that the media changed is an error, DOS generates an error 0Fh
  673. (invalid disk change) on behalf of the device. If the driver does not implement
  674. volume identification support, but has bit 11 set to 1, the driver should set a
  675. pointer to the string "NO NAME",0.
  676.  
  677.  
  678. MEDIA DESCRIPTOR
  679.  Currently the media descriptor byte has been defined for a few media types.
  680. This byte should be identical to the media byte if the device has the non-IBM
  681. format bit off. These predetermined values are:
  682.  
  683. media descriptor byte =>    1  1  1  1  1  0  0  0
  684.  (numeric order)            7  6  5  4  3  2  1  0
  685.  
  686.        BIT                MEANING
  687.  
  688.         0       0       not double sided
  689.                 1       double sided
  690.         1       0       not 8 sector
  691.                 1       8 sector
  692.         2       0       nonremoveable
  693.                 1       removeable
  694.        3-7      must be set to 1
  695.  
  696.                          ############################
  697.  
  698. BUILD BPB (BIOS Parameter Block)
  699. command code = 2        (block devices only)
  700.  
  701.         ES:BX   pointer to 22-byte request header and data structure
  702.  Format of structure:
  703.         offset   length          field
  704.         00h     13 bytes   request header
  705.         0Dh        byte    media descriptor from DOS
  706.         0Eh       dword    transfer address (buffer address)
  707.         12h       dword    pointer to BPB table
  708.  
  709. DOS calls BUILD BPB under the following two conditions:
  710.  
  711. A) If "media changed" is returned.
  712. B) If "not sure" is returned. If so, there are no used buffers. Used buffers
  713.    are buffers with changed data that have not yet been written to the disk.
  714.  
  715. The driver must do the following:
  716.  
  717. A) set the pointer to the BPB.
  718. B) set the status word in the request header.
  719.  
  720.  The driver must determine the correct media type currently in the unit to
  721. return the pointer to the BPB table. The way the buffer is used (pointer
  722. passed by DOS) is determined by the non-IBM format bit in the attribute field
  723. of the device header. If bit 13=0 (device is IBM compatible), the buffer
  724. contains the first sector of the FAT (most importantly the FAT ID byte). The
  725. driver must not alter this buffer in this case. If bit 13=1 the buffer is a
  726. one sector scratch area which can be used for anything.
  727.  
  728.  For drivers that support volume identification and disk change, the call
  729. should cause a new volume identification to be read off the disk. This call
  730. indicates that the disk has been legally changed.
  731.  
  732.  If the device is IBM compatible, it must be true that the first sector of the
  733. first FAT is located at the same sector for all possible media. This is
  734. because the FAT sector is read before the media is actually determined.
  735.  
  736.  The information relating to the BPB for a particular media is kept in the boot
  737. sector for the media. In particular, the format of the boot sector is:
  738.  
  739. ┌──────────────────────────────────────────────────────────────────────────────┐
  740. │ For DOS 2.x, 3 byte near jump (0E9h) For DOS 3.x+, 2 byte near jump (0EBh)   │
  741. │ followed by a NOP (90h)                                                      │
  742. ├──────────┬───────────────────────────────────────────────────────────────────┤
  743. │ 8 bytes  │  OEM name and version                                             │
  744. ├──────────┼─────┬─────────────────────────────────────────────────────────────┤
  745. │   BYTE   │     │  sectors per allocation unit (must be a power of 2)         │
  746. ├──────────┤     ├─────────────────────────────────────────────────────────────┤
  747. │   WORD   │  B  │  reserved sectors (strarting at logical sector 0)           │
  748. ├──────────┤     ├─────────────────────────────────────────────────────────────┤
  749. │   BYTE   │     │  number of FATs                                             │
  750. ├──────────┤     ├─────────────────────────────────────────────────────────────┤
  751. │   WORD   │  P  │  max number of root directory entries                       │
  752. ├──────────┤     ├─────────────────────────────────────────────────────────────┤
  753. │   WORD   │     │  number of sectors in logical image (total number of        │
  754. │          │     │  sectors in media, including boot sector directories, etc.) │
  755. ├──────────┤  B  ├─────────────────────────────────────────────────────────────┤
  756. │   BYTE   │     │  media descriptor                                           │
  757. ├──────────┤     ├─────────────────────────────────────────────────────────────┤
  758. │   WORD   │     │  number of sectors occupied by a single FAT                 │
  759. ├──────────┼─────┴─────────────────────────────────────────────────────────────┤
  760. │   WORD   │  sectors per track                                                │
  761. ├──────────┼───────────────────────────────────────────────────────────────────┤
  762. │   WORD   │  number of heads                                                  │
  763. ├──────────┼───────────────────────────────────────────────────────────────────┤
  764. │   WORD   │  number of hidden sectors                                         │
  765. └──────────┴───────────────────────────────────────────────────────────────────┘
  766.  
  767.  The three words at the end return information about the media. The number of
  768. heads is useful for supporting different multihead drives that have the same
  769. storage capacity but a different number of surfaces. The number of hidden
  770. sectors is useful for drive partitioning schemes.
  771.  
  772.                          ############################
  773.  
  774. INPUT / OUTPUT  (IOCTL)
  775. command code = 3   IOCTL Read
  776.                4   Read              (block or character devices)
  777.                8   Write             (block or character devices)
  778.                9   Write With Verify
  779.               12   IOCTL Write
  780.               16   Output Until Busy (character devices only)
  781.  
  782.         ES:BX   pointer to 24-byte request header and data structure
  783.  
  784.   Format of structure:
  785.         offset    length          field
  786.         00h     13 bytes     request header
  787.         0Dh        byte      media descriptor byte from BPB
  788.         0Eh       dword      transfer address (buffer address)
  789.         12h        word      byte/sector count
  790.         14h        word      starting sector number (block devices)
  791.                              [no meaning on character devices]
  792.         16h       dword      (DOS 3.0+) pointer to the volume ID if error code
  793.                              0Fh is returned
  794.  
  795. The driver must perform the following:
  796.         A) set the status word in the request header
  797.         B) perform the requested function
  798.         C) set the actual number of sectors or bytes tranferred
  799.  
  800.  No error checking is performed on an IOCTL I/O call. However, the driver must
  801. set the return sector or byte count to the actual number of bytes transferred.
  802.  
  803.  Under certain circumstances a block device driver may be asked to do a write
  804. operation of 64k bytes that seems to be a "wrap around" of the transfer address
  805. in the BIOS I/O packet. This arises due to an optimization added to write code
  806. in DOS. It will only happen in writes that are within a sector size of 64k on
  807. files that are being extended past the current end of file. It is allowable for
  808. the device driver to ignore the balance of the write that wraps around, if it
  809. so chooses. For example, a write of 10000h bytes worth of sectors with a
  810. transfer address of XXX:1 ignores the last two bytes. A user program can never
  811. request an I/O of more than 0FFFFh bytes and cannot wrap around (even to 0) in
  812. the transfer segment, so in that case the last two bytes can be ignored.
  813.  
  814.  A program that uses DOS function calls can never request an input or output
  815. function of more than 0FFFFh bytes, therefore, a wrap around in the transfer
  816. (buffer) segment can never occur. It is for this reason you can ignore bytes
  817. that would have wrapped around in the tranfer segment.
  818.  
  819.  If the driver returns an error code of 0Fh (invalid disk change) it must put
  820. a DWORD pointer to an ASCIIZ string which is the correct volume ID to ask the
  821. user to reinsert the disk.
  822.  
  823. DOS 3.0+:
  824.  The reference count of open files on the field (maintained by the OPEN and
  825. CLOSE calls) allows the driver to determine when to return error 0Fh. If there
  826. are no open files (reference count=0) and the disk has been changed, the I/O
  827. is all right, and error 0Fh is not returned. If there are open files
  828. (reference count > 0) and the disk has been changed, an error 0Fh condition
  829. may exist.
  830.  
  831.                          ############################
  832.  
  833. NONDESTRUCTIVE INPUT NO WAIT
  834. command code = 5        (character devices only)
  835.         Reads a character from input stream but does not remove it from the
  836.         buffer
  837.  
  838.         ES:BX   pointer to 14-byte request header and data structure
  839.  Format of structure:
  840.         offset    length          field
  841.         00h     13 bytes   request header
  842.         0Dh        byte    read from device
  843.  
  844. The driver must do the following:
  845.         A) return a byte from the device
  846.         B) set the status word in the request header.
  847.  
  848.  If the character device returns busy bit=0 (characters in the buffer), then
  849. the next character that would be read is returned. This character is not removed
  850. form the buffer (hence the term nondestructive input). This call allows DOS to
  851. look ahead one character.
  852.  
  853.                          ############################
  854.  
  855. STATUS
  856. command codes =  6   Input Status      (character devices only)
  857.                 10   Output Status     (character devices only)
  858.         Check for characters waiting in input buffer
  859.  
  860.         ES:BX   pointer to 13-byte request header
  861.  
  862. This driver must perform the following:
  863.         A) perform the requested function
  864.         B) set the busy bit
  865.         C) set the status word in the request header.
  866.  
  867. The busy bit is set as follows:
  868.  
  869.  For input on unbuffered character devices: if the busy bit (bit 9) is 1 on
  870. return, a write request would wait for completion of a current request. If the
  871. busy bit is 0, there is no current request. Therefore, a write request would
  872. start immediately.
  873.  
  874.  For input on buffered character devices: if the busy bit is 1 on return, a
  875. read request does to the physical device. If the busy bit is 0, there are
  876. characters in the device buffer and a read returns quickly. It also indicates
  877. that a user has typed something. DOS assumes all character devices have a type-
  878. ahead input buffer. Devices that do not have this buffer should always return
  879. busy=0 so that DOS does not hang waiting for information to be put in a buffer
  880. that does not exist.
  881.  
  882.                          ############################
  883.  
  884. FLUSH INPUT BUFFERS
  885. command code = 7        (character devices only)
  886.         Forces all data in buffers to specified device.
  887.  
  888.         ES:BX   pointer to 13-byte request header
  889.  
  890.  This call tells the driver to flush (terminate) all pending requests that it
  891. has knowledge of. Its primary use is to flush the input queue on character
  892. devices.
  893.  
  894.  The driver must set the status word in the request header upon return.
  895.  
  896.                          ############################
  897.  
  898. FLUSH OUTPUT BUFFERS
  899. command code 11         (character devices only)
  900.         Forces all data in buffers to specified device.
  901.  
  902.         ES:BX   pointer to 13-byte request header
  903.  
  904.  
  905.  This call tells the driver to flush all output buffers and discards any
  906. pending requests. Its primary use is to flush the output queue on character
  907. devices.
  908.  
  909.  The driver must set the status word in the request header upon return.
  910.  
  911.                          ############################
  912.  
  913. OPEN or CLOSE  (DOS 3.0+)
  914. command code = 13   Open      (block or character devices)
  915.                14   Close     (block or character devices)
  916.  
  917.         ES:BX   pointer to 13-byte static request header
  918.  
  919.  These calls are designed to give the device information about the current file
  920. activity on the device if bit 11 of the attribute word is set. On block
  921. devices, these calls can be used to manage local buffering. The device can keep
  922. a reference count. Every OPEN causes the device to increment the reference
  923. count. Every CLOSE causes the device to decrement the reference count. When the
  924. reference count is 0, if means there are no open files in the device. Therefore,
  925. the device should flush buffers inside the device it has written to because now
  926. the user can change the media on a removeable media drive. If the media had been
  927. changed, it is advisable to reset the reference count to 0 without flushing the
  928. buffers. This can be thought of as "last close causes flush". These calls are
  929. more useful on character devices. The OPEN call can be used to send a device
  930. initialization string. On a printer, this could cause a string to be sent to set
  931. the font, page size, etc. so that the printer would always be in a known state
  932. in the I/O stream. Similarly, a CLOSE call can be used to send a post string
  933. (like a form feed) at the end of an I/O stream. Using IOCTL to set these pre and
  934. post strings provides a flexible mechanism of serial I/O device stream control.
  935.  
  936.  Since all processes have access to STDIN, STDOUT, STDERR, STDAUX, and STDPRN
  937. (handles 0, 1, 2, 3, and 4) the CON, AUX, and PRN devices are always open.
  938.  
  939.                          ############################
  940.  
  941. REMOVABLE MEDIA  (DOS 3.0+)
  942. command code = 15       (block devices only)
  943.         This call identifies the media type as removable or nonremovable.
  944.  
  945.         ES:BX   pointer to 13-byte static request header
  946.  
  947.  To use this call, set bit 11 (removable media) of the attribute field to 1.
  948. Block devices can only use this call through a subfunction of the IOCTL
  949. function call (int 21h fn44h).
  950.  This call is useful because it allows a utility to know whether it is dealing
  951. with a nonremovable media drive or with a removable media drive. For example,
  952. the FORMAT utility needs to know whether a drive is removable or nonremovable
  953. because it prints different versions of some prompts.
  954.  
  955. note    No error checking is performed. It is assumed that this call always
  956.         succeeds.
  957.  
  958.  
  959. THE CLOCK$ DEVICE├─────────────────────────────────────────────────────────────
  960.  
  961.  To allow a clock board to be integrated into the system for TIME and DATE,
  962. the CLOCK$ device is used. This device defines and performs functions like any
  963. other character device (most functions will be reset done bit, reset error bit,
  964. and return). When a read or write to this device occurs, 6 bytes are
  965. transferred. The first 2 bytes are a word, which is the count of days since
  966. 01-01-80. The third byte is minutes, the fourth is hours, the fifth is
  967. hundredths of a second, and the sixth is seconds.
  968.  
  969.  Reading the CLOCK$ device gets the date and time, writing to it sets the date
  970. and time. CLOCK$ is normally called only when the system is initializing or if
  971. the system time and date are set (DOS 3.3+). DOS carries the system time and
  972. date internally after receiving it from the CLOCK$ driver.
  973.  
  974.  
  975.  
  976.  
  977.